using System;
using System.Collections.Generic;
using System.Text;
using Koda.Search;
using System.Text.RegularExpressions;

namespace Koda.Search.Finders
{
    public abstract class VsFinderBase : IVsItemFinder
    {
        private List<VsItem> cache;
        private List<VsItem> result;
        private string keyword;

        public string Keyword
        {
            get
            {
                return this.keyword;
            }
        }

        public IList<VsItem> Result
        {
            get 
            {
                return this.result;
            }
        }

        public int Search(string keyword)
        {
            this.keyword = keyword;

            if (this.cache == null)
            {
                this.cache = this.Refresh();
                this.cache.Sort(SortByName);
            }

            Regex regex = this.CreateReqularExpression(keyword);

            this.result = new List<VsItem>();

            foreach (VsItem item in this.cache)
            {
                if (regex.Match(item.Name).Success)
                {
                    this.result.Add(item);
                }
            }

            return this.result.Count;
        }

        public abstract bool OpenItem(VsItem item);
        protected abstract List<VsItem> Refresh();

        private int SortByName(VsItem itemX, VsItem itemY)
        {
            return itemX.Name.CompareTo(itemY.Name);
        }

        private Regex CreateReqularExpression(string pattern)
        {
            if (this.ContainsWildcard(pattern))
            {
                pattern = "^" + pattern.Replace("*", ".*");
            }
            else if (this.ContainsOnlyUpperCaseLetters(pattern))
            {
                StringBuilder sb = new StringBuilder();
                foreach (char c in pattern)
                {
                    sb.Append(c);
                    sb.Append(".*");
                }

                pattern = "^" + sb.ToString();
            }
            else
            {
                pattern = "^" + pattern;
            }

            return new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
        }

        private bool ContainsWildcard(string text)
        {
            return text.Contains("*");
        }

        private bool ContainsOnlyUpperCaseLetters(string text)
        {
            for (int i = 0; i < text.Length; i++)
            {
                if (!Char.IsUpper(text[i]))
                    return false;
            }

            return true;
        }
    }
}
